#ifndef     __FLASH_H
#define     __FLASH_H

#include <stdint.h>
#include "../utils/md5.h"
#include <string.h>

namespace driver {

namespace flash {

const uint32_t Base = 60 * 1024; 
const uint32_t PageSize = 1024;

bool erase(uint32_t addr, uint32_t size);
bool write(uint32_t addr, const void *buf, uint32_t size);
void read(uint32_t addr, void *buf, uint32_t size);

template <typename M>
struct StoreObject_t {
    M obj;
    uint8_t sum[16];
};

template <typename M, uint32_t Addr>
struct Store {

    bool load() {
        read(Addr, &store, sizeof (store));
        uint8_t s[16];
        utils::md5::sum(&store.obj, sizeof (store.obj), s);
        bool ret = 0 == memcmp(s, store.sum, 16);
        if (!ret) {
            store.obj.reset();
        }
        return ret;
    }

    bool save() {
        utils::md5::sum(&store.obj, sizeof(store.obj), store.sum);
        bool ret = erase(Addr, sizeof (store));
        if (!ret) {
            return false;
        }
        return write(Addr, &store, sizeof (store));
    }

    inline M* operator->() {
        return &store.obj;
    }

private:
    StoreObject_t<M> store;
};

}

}


#endif
